
package com.insigma.business.qrcode.soldier.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Sets;

import com.insigma.business.common.utils.PriInfoHandleUtil;
import com.insigma.business.qrcode.common.dto.SoldierApplyTypeEnum;
import com.insigma.business.qrcode.common.service.SequenceGenerator;
import com.insigma.business.qrcode.common.util.AdminAreaCodeUtils;
import com.insigma.business.qrcode.common.vo.ProcessStatusEnum;
import com.insigma.business.qrcode.soldier.dao.GovEmployeeRoleDao;
import com.insigma.business.qrcode.soldier.dao.SoldierApplyInfoDao;
import com.insigma.business.qrcode.soldier.dao.SoldierBasicInfoDao;
import com.insigma.business.qrcode.soldier.dto.SequenceNameConstant;
import com.insigma.business.qrcode.soldier.dto.SoldierApplyInfoBSearcher;
import com.insigma.business.qrcode.soldier.entity.*;
import com.insigma.business.qrcode.soldier.service.SoldierApplyInfoService;
import com.insigma.business.qrcode.soldier.service.SoldierBasicInfoService;
import com.insigma.business.qrcode.soldier.service.SoldierService;
import com.insigma.business.qrcode.soldier.service.SoldierTypeService;
import com.insigma.business.qrcode.soldier.util.BizCheckUtil;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;


@Service("soldierApplyInfoService")
public class SoldierApplyInfoServiceImpl implements SoldierApplyInfoService {

    @Autowired(required = false)
    private SoldierApplyInfoDao soldierApplyInfoDao;

    @Autowired(required = false)
    private SequenceGenerator sequenceGenerator;

    @Autowired(required = false)
    private SoldierBasicInfoDao soldierBasicInfoDao;

    @Autowired
    @Lazy
    private SoldierBasicInfoService soldierBasicInfoService;

    @Autowired(required = false)
    @Lazy
    private SoldierService soldierService;

    @Autowired(required = false)
    private GovEmployeeRoleDao govEmployeeRoleDao;

    @Resource
    SoldierTypeService soldierTypeService;


    private static Logger LOGGER = LoggerFactory.getLogger(SoldierApplyInfoService.class);

    
    @Override
    public List<SoldierApplyInfoDO> search(final SoldierApplyInfoBSearcher soldierApplyInfoBSearcher) {
        return soldierApplyInfoDao.search(soldierApplyInfoBSearcher);
    }

    
    @Override
    public SoldierApplyInfoDO get(final String id) {
        return soldierApplyInfoDao.get(id);
    }

    
    @Override
    public Integer insert(final SoldierApplyInfoDO soldierApplyInfoDO) {
        soldierApplyInfoDO.setId(sequenceGenerator.genKey(SequenceNameConstant.SOLDIER_APPLY_INFO_ID));
        if (soldierApplyInfoDO.getHolded() == null) {
            soldierApplyInfoDO.setHolded(false);
        }

        if (Strings.isBlank(soldierApplyInfoDO.getApplyType())) {
            soldierApplyInfoDO.setApplyType(SoldierApplyTypeEnum.NORMAL.name());
        }

        
        if (!soldierApplyInfoDO.getApplyType().equals(SoldierApplyTypeEnum.TEMPORARY.name())) {
            SoldierApplyInfoDO byIdCardNo = soldierApplyInfoDao.getByIdCardNo(soldierApplyInfoDO.getIdCardNo(), soldierApplyInfoDO.getApplyType());
            BizCheckUtil.checkIsNull(byIdCardNo, "您已申请！");
        }
        soldierApplyInfoDO.setIsPush("0");
        soldierApplyInfoDO.setMobile(PriInfoHandleUtil.encrypt(soldierApplyInfoDO.getMobile()));
        soldierApplyInfoDO.setIdCardNo(PriInfoHandleUtil.encrypt(soldierApplyInfoDO.getIdCardNo()));
        return soldierApplyInfoDao.insert(soldierApplyInfoDO);
    }

    
    @Override
    public Integer update(final SoldierApplyInfoDO soldierApplyInfoDO) {
        if (soldierApplyInfoDO.getHolded() == null) {
            soldierApplyInfoDO.setHolded(false);
        }
        return soldierApplyInfoDao.update(soldierApplyInfoDO);
    }

    @Override
    public Integer delete(String id, String modifierType, String modifierId) {
        return soldierApplyInfoDao.delete(id, modifierType, modifierId);
    }


    @Override
    public List<SoldierApplyInfoDO> listByProcInstIds(Set<String> procInstIds) {
        return soldierApplyInfoDao.listByProcInstIds(procInstIds);
    }

    @Override
    public SoldierApplyInfoDO getByIdCardNo(String idCardNo) {
        return soldierApplyInfoDao.getByIdCardNo(PriInfoHandleUtil.encrypt(idCardNo), SoldierApplyTypeEnum.NORMAL.name());
    }

    @Override
    public void afterSoldierChecked(String processInstanceId) {
        LOGGER.info("afterSoldierChecked, processInstId:{}", processInstanceId);
        List<SoldierApplyInfoDO> soldierApplyInfoDOS = soldierApplyInfoDao.listByProcInstIds(Sets.newHashSet(processInstanceId));
        
        for (SoldierApplyInfoDO soldierApplyInfoDO : soldierApplyInfoDOS) {
            SoldierDO soldierDO = soldierService.get(soldierApplyInfoDO.getSoldierId());
            soldierDO.setMobile(soldierApplyInfoDO.getMobile());
            soldierDO.setModifyDatetime(new Date());
            soldierService.update(soldierDO);

            
            soldierApplyInfoDO.setStatus(ProcessStatusEnum.SUCCESS.name());
            soldierApplyInfoDao.update(soldierApplyInfoDO);

            String idCardNo = soldierApplyInfoDO.getIdCardNo();

            SoldierBasicInfoDO bySoldierId = soldierBasicInfoDao.getBySoldierId(soldierApplyInfoDO.getSoldierId());
            if (bySoldierId != null) {
                
                LOGGER.error("soldier id 重复， soldier info :{}", soldierApplyInfoDO.getSoldierId());
                bySoldierId.setSoldierId("");
                soldierBasicInfoDao.update(bySoldierId);
            }

            SoldierBasicInfoDO soldierBasicInfoDO = soldierBasicInfoDao.getByIdCardNo(idCardNo);
            if (soldierBasicInfoDO == null) {
                
                SoldierBasicInfoDO newSoldier = new SoldierBasicInfoDO();
                BeanUtils.copyProperties(soldierApplyInfoDO, newSoldier);
                newSoldier.setCreateDatetime(new Date());
                soldierBasicInfoDao.insert(newSoldier);
            } else {
                
                soldierBasicInfoDO.setSoldierId(soldierApplyInfoDO.getSoldierId());
                soldierBasicInfoDO.setSoldierTypeDictCode(soldierApplyInfoDO.getSoldierType());
                soldierBasicInfoDao.update(soldierBasicInfoDO);
            }
        }
    }

    @Override
    public List<SoldierApplyInfoDO> listByProcInstIdsSearcher(SoldierApplyInfoBSearcher soldierApplyInfoBSearcher) {
        return soldierApplyInfoDao.searchByProcInstIds(soldierApplyInfoBSearcher);
    }

    @Override
    public SoldierApplyInfoDO getBySoldierId(String soldierId) {
        return soldierApplyInfoDao.getBySoldierId(soldierId, SoldierApplyTypeEnum.NORMAL.name());
    }

    @Override
    public List<SoldierApplyInfoDO> searchByAreaLikeStatusManual(SoldierApplyInfoBSearcher soldierApplyInfoBSearcher) {
        List<SoldierApplyInfoDO> res =  soldierApplyInfoDao.searchByAreaLikeStatusManual(soldierApplyInfoBSearcher);
        if (!CollectionUtil.isEmpty(res)) {
            for (SoldierApplyInfoDO soldierApplyInfoDO : res) {
                soldierApplyInfoDO.setIdCardNo(PriInfoHandleUtil.decrypt(soldierApplyInfoDO.getIdCardNo()));
                soldierApplyInfoDO.setMobile(PriInfoHandleUtil.decrypt(soldierApplyInfoDO.getMobile()));
            }
        }
        return res;
    }

    @Override
    public List<SoldierApplyInfoDO> searchByAreaLikeAndStatusList(SoldierApplyInfoBSearcher soldierApplyInfoBSearcher) {
        return soldierApplyInfoDao.searchByAreaLikeAndStatusList(soldierApplyInfoBSearcher);
    }

    @Override
    public void afterSoldierApplySucc(String id) {
        LOGGER.info("applyid:{}", id);
        SoldierApplyInfoDO soldierApplyInfoDO = soldierApplyInfoDao.get(id);
        
//        SoldierDO soldierDO = soldierService.get(soldierApplyInfoDO.getSoldierId());
//        soldierDO.setMobile(soldierApplyInfoDO.getMobile());
//        soldierDO.setModifyDatetime(new Date());
//        soldierService.update(soldierDO);

        String idCardNo = soldierApplyInfoDO.getIdCardNo();

        SoldierBasicInfoDO bySoldierId = soldierBasicInfoDao.getBySoldierId(soldierApplyInfoDO.getSoldierId());
        if (bySoldierId != null) {
            
//            LOGGER.error("soldier id 重复， soldier info :{}", soldierApplyInfoDO.getSoldierId());
//            bySoldierId.setSoldierId("");
//            soldierBasicInfoDao.update(bySoldierId);
        }

//        SoldierBasicInfoDO soldierBasicInfoDO = soldierBasicInfoDao.getByIdCardNo(idCardNo);
//        if (soldierBasicInfoDO == null) {
//
//            SoldierBasicInfoDO newSoldier = new SoldierBasicInfoDO();
//            BeanUtils.copyProperties(soldierApplyInfoDO, newSoldier);
//            newSoldier.setCreateDatetime(new Date());
//            newSoldier.setAttachment(null);
//            soldierBasicInfoService.insert(newSoldier);
//
//
//            String soldierType = soldierApplyInfoDO.getSoldierType();
//            if (Strings.isNotBlank(soldierType)) {
//                for (String s : soldierType.split(",")) {
//                    SoldierTypeDO soldierTypeDO = new SoldierTypeDO();
//                    soldierTypeDO.setSoldierId(soldierApplyInfoDO.getId());
//                    soldierTypeDO.setSoldierType(s);
//                    soldierTypeDO.setAdminAreaCode(soldierApplyInfoDO.getResidentAdminAreaCode());
//                    try {
//                        soldierTypeService.insert(soldierTypeDO);
//                    } catch (Exception e) {
//                        LOGGER.error("soldierType插入报错，e:{}", e);
//                    }
//                }
//            }
//        } else {
//            soldierBasicInfoDO.setSoldierId(soldierApplyInfoDO.getSoldierId());
//            soldierBasicInfoDO.setResidentAdminAreaCode(soldierApplyInfoDO.getResidentAdminAreaCode());
//            soldierBasicInfoDO.setResidentAddress(soldierApplyInfoDO.getResidentAddress());
//            soldierBasicInfoDO.setMobile(soldierApplyInfoDO.getMobile());
//            soldierBasicInfoDO.setSoldierTypeDictCode(soldierApplyInfoDO.getSoldierTypeDictCode());
//            soldierBasicInfoDO.setSoldierType(soldierApplyInfoDO.getSoldierType());
//            soldierBasicInfoDO.setRetireDatetime(soldierApplyInfoDO.getRetireDatetime());
//            soldierBasicInfoDO.setBirthday(soldierApplyInfoDO.getBirthday());
//            soldierBasicInfoDO.setEntryDatetime(soldierApplyInfoDO.getEntryDatetime());
//
//            soldierBasicInfoDao.update(soldierBasicInfoDO);
//        }
    }

    @Override
    public List<Map<String, Object>> querySoldierManualCheckDetail(String adminAreaCode) {
        String cutdAreaCode = AdminAreaCodeUtils.getCutdAreaCode(adminAreaCode);
        int nextCodeLength = AdminAreaCodeUtils.getNextCodeLength(adminAreaCode);
        int padSize = 12 - nextCodeLength;
        String padString = com.google.common.base.Strings.padStart("", padSize, '0');

        return soldierBasicInfoDao.querySoldierManualCheckDetail(cutdAreaCode + "%", nextCodeLength, padString, null, null);
    }

    @Override
    public List<Map<String, Object>> querySoldierManualCheckDetail(String adminAreaCode, Date beginDate, Date endDate) {
        String cutdAreaCode = AdminAreaCodeUtils.getCutdAreaCode(adminAreaCode);
        int nextCodeLength = AdminAreaCodeUtils.getNextCodeLength(adminAreaCode);
        int padSize = 12 - nextCodeLength;
        String padString = com.google.common.base.Strings.padStart("", padSize, '0');

        return soldierBasicInfoDao.querySoldierManualCheckDetail(cutdAreaCode + "%", nextCodeLength, padString, beginDate, endDate);
    }

    @Override
    public List<DataStatsCDO> querySoldierManualStats(String adminAreaCode, String type) {
        String cutdAreaCode = AdminAreaCodeUtils.getCutdAreaCode(adminAreaCode);
        int level = AdminAreaCodeUtils.getLevel(adminAreaCode);
        int nextCodeLength = AdminAreaCodeUtils.getNextCodeLength(adminAreaCode);

        return soldierBasicInfoDao.querySoldierManualStats(cutdAreaCode + "%", level + 1, nextCodeLength, type, null, null);
    }

    @Override
    public List<DataStatsCDO> querySoldierManualStats(String adminAreaCode, String type, Date beginDate, Date endDate) {
        String cutdAreaCode = AdminAreaCodeUtils.getCutdAreaCode(adminAreaCode);
        int level = AdminAreaCodeUtils.getLevel(adminAreaCode);
        int nextCodeLength = AdminAreaCodeUtils.getNextCodeLength(adminAreaCode);

        return soldierBasicInfoDao.querySoldierManualStats(cutdAreaCode + "%", level + 1, nextCodeLength, type, beginDate, endDate);
    }

    @Override
    public Integer realDelete(String id) {
        return soldierApplyInfoDao.realDelete(id);
    }

    @Override
    public Integer realDelete(String id, String modifierType, String modifierId) {
        return null;
    }

    @Override
    public Integer deleteByIdCardNo(String idCardNo, String modifierType, String modifierId) {
        return null;
    }


    @Override
    public List<SoldierApplyInfoDO> listBySoldierId(String soldierId) {
        return soldierApplyInfoDao.listBySoldierId(soldierId, null);
    }

    @Override
    public List<SoldierApplyInfoDO> listBySoldierId(String soldierId, String applyType) {
        return soldierApplyInfoDao.listBySoldierId(soldierId, applyType);
    }

    @Override
    public SoldierApplyInfoDO getByIdCardNoOfType(String idCardNo, String applyType) {
        return soldierApplyInfoDao.getByIdCardNoOfType(PriInfoHandleUtil.encrypt(idCardNo), applyType);
    }

    @Override
    public SoldierApplyInfoDO getByIdCardInfo(String idCardNo) {
        return soldierApplyInfoDao.getByIdCardInfo(PriInfoHandleUtil.encrypt(idCardNo));
    }

    @Override
    public SoldierApplyInfoDO getLastApplyOfSoldierId(String soldierId, String applyType) {
        return soldierApplyInfoDao.getLastApplyOfSoldierId(soldierId, applyType);
    }

    @Override
    public Integer countQrSuccessByAreaAndType(String areaLike, String applyType) {
        return soldierApplyInfoDao.countQrSuccessByAreaAndType(areaLike, applyType);
    }

    @Override
    public Integer countQrSuccessByAreaAndTime(String adminAreaCode, Date beginDate, Date endDate) {
        return soldierApplyInfoDao.countQrSuccessByAreaAndTime(AdminAreaCodeUtils.getCutdAreaCode(adminAreaCode), beginDate, endDate);
    }

    @Override
    public List<SoldierApplyInfoDO> getByIdCardAndAreaCode(String idCardNo, String areaCode) {
        return soldierApplyInfoDao.getByIdCardAndAreaCode(PriInfoHandleUtil.encrypt(idCardNo),areaCode);
    }

    @Override
    public List<SoldierApplyInfoDO> getByMobile(String mobile) {
        return soldierApplyInfoDao.getByMobile(PriInfoHandleUtil.encrypt(mobile));
    }

    @Override
    public List<SoldierApplyInfoDO> getByHoldMobile(String mobile) {
        return soldierApplyInfoDao.getByHoldMobile(PriInfoHandleUtil.encrypt(mobile));
    }

}
